#pragma once
#include "mysql.hpp"
#include "friend_apply-odb.hxx"
#include "log.hpp"

#include <vector>
class FriendApplyTable {
public:
    using ptr = std::shared_ptr<FriendApplyTable>;
    FriendApplyTable(const std::shared_ptr<odb::core::database> &db) : _db(db) {}
    

    bool insert(FriendApply apply) {
        try {
            odb::transaction trans(_db->begin());
            _db->persist(apply);
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("插入好友申请失败: {}->{}:{}", apply.user_id(), apply.peer_id(), e.what());
            return false;
        }
        LOG_INFO("插入好友申请成功: {}->{}", apply.user_id(), apply.peer_id());
        return true;
    }


    bool remove(const std::string& user_id, const std::string& peer_id) {
        using query_t = odb::query<FriendApply>;
        try {
            odb::transaction trans(_db->begin());
            _db->erase_query<FriendApply>(query_t::user_id == user_id && query_t::peer_id == peer_id);
            trans.commit();
        }
        catch(const odb::exception &e) {
            LOG_ERROR("删除好友申请失败: {}-{}:{}", user_id, peer_id, e.what());
            return false;
        }
        LOG_INFO("删除好友申请成功: {}-{}", user_id, peer_id);
        return true;
    }


    bool exists(const std::string& user_id, const std::string& peer_id) {
        using query_t = odb::query<FriendApply>;
        using result_t = odb::result<FriendApply>;
        bool ret = false;
        result_t r;
        try {
            odb::transaction trans(_db->begin());
            r = _db->query<FriendApply>(query_t::user_id == user_id && query_t::peer_id == peer_id);
            if(!r.empty())
                ret = true;
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("查询好友关系失败: {}-{}:{}", user_id, peer_id, e.what());
            return false;
        }
        return ret;
    }


    std::vector<std::string> applyUsers(const std::string &user_id) {
        using query_t = odb::query<FriendApply>;
        using result_t = odb::result<FriendApply>;
        std::vector<std::string> ret;

        try {
            odb::transaction trans(_db->begin());
            result_t r = _db->query<FriendApply>(query_t::peer_id == user_id);
            for (const auto &apply : r) {
                ret.emplace_back(apply.user_id());
            }
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("查询好友申请失败: {}:{}", user_id, e.what());
            return {};
        }

        LOG_DEBUG("查询好友申请成功: {}:{}", user_id, ret.size());
        return ret;
    }
private:
    std::shared_ptr<odb::core::database> _db;
};